/**********************************************************************************************/
/* FBL_Exceptions.h																		 	  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006                                        					  */
/* All Rights Reserved.                                                 					  */
/**********************************************************************************************/

#ifndef _FBL_Exceptions_h
	#define _FBL_Exceptions_h

#include <VShared/FBL/publ/Headers/FBL.h>

#include <VShared/FBL/publ/Errors/FBL_ErrorMap.h> 


/**********************************************************************************************/
FBL_Begin_Namespace

/**********************************************************************************************/
class String;

interface I_Connection;


/**********************************************************************************************/
// This is a normal exception class to be used in the kernel.
// You can always catch xException exception to catch ANY exception from database kernel. 
//
// We do not use String class here to break circular dependancy on it.
class FBL_SHARED_EXP_CLASS xException 			
{
	public://///////////////////////////////////////////////////////////////////////////////////
	
	//------------------
	// Construction

							xException( 
								ERROR_TYPE 		inErrorCode = ERR_INTERNAL_ERROR,
								const UChar* 	inArg1 = 0,
								const UChar* 	inArg2 = 0,
								const UChar* 	inArg3 = 0 );

							xException( 
								ERROR_TYPE 		inErrorCode,
								const char* 	inArg1,
								const char* 	inArg2 = 0,
								const char* 	inArg3 = 0 );

							xException( 
								ERROR_TYPE 		inErrorCode,
								const String& 	inFinalMessage,
								I_Connection* 	inConn );

							xException( const xException& inExc );
														
virtual						~xException( void );

        xException&         operator=( const xException& inOther );


	public://///////////////////////////////////////////////////////////////////////////////////
	
		//------------------
		// ErrProperties

		ERROR_TYPE			get_ErrorCode( void ) const 
								{ return mErrorCode; }

virtual const String&		get_ErrorString( void ) const;

		const String& 		get_Param( ulong inIndex ) const throw();

		I_Connection*		get_Connection( void ) const throw() 
								{ return mpConnection; }


	protected://///////////////////////////////////////////////////////////////////////////	
    
		void				Clear( void );

							// The purpose is to reject this class instantiation.
virtual	void				DummyCall( void ) const throw() = 0;

		
	protected://///////////////////////////////////////////////////////////////////////////
	
		ERROR_TYPE 			mErrorCode;
		String*				mArgs[3];
		I_Connection*		mpConnection;	// Pointer to the connection object to get error description string.
};


#pragma mark -


/**********************************************************************************************/
struct ErrorEntry
{
	ERROR_TYPE	mCode;
	const char*	mSymbol;
	UChar*		mDescription;
};


/**********************************************************************************************/
/**	Finds error entry in the map of existing error entries.
	@param inErrorCode - error code to find to.
	@return pointer to those entry if it was found or NULL,
		if there is no such error code. */
FBL_SHARED_EXP ErrorEntry* FindErrorEntry( ERROR_TYPE inErrorCode );
FBL_SHARED_EXP ErrorEntry* FindErrorEntry( const char*	inErrorStr );


/**********************************************************************************************/
#define DECLARE_EXCEPTION(NewExc, BaseExc, kErr)							\
	class NewExc : public BaseExc 											\
	{																		\
		public:																\
			NewExc( ERROR_TYPE inErr = (kErr),								\
				const UChar* inArg1 = 0,									\
				const UChar* inArg2 = 0,									\
				const UChar* inArg3 = 0 )									\
				: BaseExc( inErr, inArg1, inArg2, inArg3 )					\
			{																\
				FBL_CHECK( mErrorCode >> 12 == kErr >> 12 );				\
			}																\
																			\
			NewExc( ERROR_TYPE inErr,										\
				const char* inArg1,											\
				const char* inArg2 = 0,										\
				const char* inArg3 = 0 )									\
				: BaseExc( inErr, inArg1, inArg2, inArg3 )					\
			{																\
				FBL_CHECK( mErrorCode >> 12 == kErr >> 12 );				\
			}																\
																			\
			NewExc( ERROR_TYPE inErr,										\
				const String& inFinalMessage,								\
				I_Connection* pConn)										\
				: BaseExc( inErr, inFinalMessage, pConn )					\
			{																\
				FBL_CHECK( mErrorCode >> 12 == kErr >> 12 );				\
			}																\
																			\
		protected:															\
																			\
	virtual	void			DummyCall( void ) const throw() {}				\
	};


/**********************************************************************************************/
#define IMPLEMENT_EXCEPTION(NewExc, BaseExc, kErr)\
	NewExc::NewExc( ERROR_TYPE err ) : BaseExc( err ) {}


#pragma mark -


/**********************************************************************************************/
/** Formats error message for the given error 
	code with the given parameters. */
FBL_SHARED_EXP const UChar* FormatErrorMessage ( 
	ErrorEntry*  inErrorEntry, 
	const UChar* const inArgs[] );


FBL_SHARED_EXP const char* FormatErrorMessage ( 
	ErrorEntry*  inErrorEntry, 
	const char* const inArgs[] );


/**********************************************************************************************/
FBL_End_Namespace


/**********************************************************************************************/
#include <VShared/FBL/publ/Errors/FBL_ErrorGroups.h>


/**********************************************************************************************/
#endif // _FBL_Exceptions_h








